home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / rampart.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  8KB  |  332 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw/rampart.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ****************************************************************************
  8.  
  9.     Motion Object encoding
  10.     ----------------------
  11.         4 16-bit words are used
  12.  
  13.         Word 1:
  14.             Bits  0-7  = link to the next motion object
  15.  
  16.         Word 2:
  17.             Bit   15   = horizontal flip
  18.             Bits  0-11 = image index
  19.  
  20.         Word 3:
  21.             Bits  7-15 = horizontal position
  22.             Bits  0-3  = motion object palette
  23.  
  24.         Word 4:
  25.             Bits  7-15 = vertical position
  26.             Bits  4-6  = horizontal size of the object, in tiles
  27.             Bits  0-2  = vertical size of the object, in tiles
  28.  
  29. ***************************************************************************/
  30.  
  31. #include "driver.h"
  32. #include "machine/atarigen.h"
  33. #include "vidhrdw/generic.h"
  34.  
  35. #define XCHARS 43
  36. #define YCHARS 30
  37.  
  38. #define XDIM (XCHARS*8)
  39. #define YDIM (YCHARS*8)
  40.  
  41.  
  42.  
  43. /*************************************
  44.  *
  45.  *    Statics
  46.  *
  47.  *************************************/
  48.  
  49. static int *color_usage;
  50.  
  51.  
  52.  
  53. /*************************************
  54.  *
  55.  *    Prototypes
  56.  *
  57.  *************************************/
  58.  
  59. static const UINT8 *update_palette(void);
  60.  
  61. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  62. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  63.  
  64.  
  65.  
  66. /*************************************
  67.  *
  68.  *    Video system start
  69.  *
  70.  *************************************/
  71.  
  72. int rampart_vh_start(void)
  73. {
  74.     static struct atarigen_mo_desc mo_desc =
  75.     {
  76.         256,                 /* maximum number of MO's */
  77.         8,                   /* number of bytes per MO entry */
  78.         2,                   /* number of bytes between MO words */
  79.         0,                   /* ignore an entry if this word == 0xffff */
  80.         0, 0, 0xff,          /* link = (data[linkword] >> linkshift) & linkmask */
  81.         0                    /* render in reverse link order */
  82.     };
  83.  
  84.     static struct atarigen_pf_desc pf_desc =
  85.     {
  86.         8, 8,                /* width/height of each tile */
  87.         XCHARS, YCHARS,        /* number of tiles in each direction */
  88.         1                    /* non-scrolling */
  89.     };
  90.  
  91.     /* allocate color usage */
  92.     color_usage = malloc(sizeof(int) * 256);
  93.     if (!color_usage)
  94.         return 1;
  95.     color_usage[0] = XDIM * YDIM;
  96.  
  97.     /* initialize the playfield */
  98.     if (atarigen_pf_init(&pf_desc))
  99.     {
  100.         free(color_usage);
  101.         return 1;
  102.     }
  103.  
  104.     /* initialize the motion objects */
  105.     if (atarigen_mo_init(&mo_desc))
  106.     {
  107.         atarigen_pf_free();
  108.         free(color_usage);
  109.         return 1;
  110.     }
  111.  
  112.     return 0;
  113. }
  114.  
  115.  
  116.  
  117. /*************************************
  118.  *
  119.  *    Video system shutdown
  120.  *
  121.  *************************************/
  122.  
  123. void rampart_vh_stop(void)
  124. {
  125.     /* free data */
  126.     if (color_usage)
  127.         free(color_usage);
  128.     color_usage = 0;
  129.  
  130.     atarigen_pf_free();
  131.     atarigen_mo_free();
  132. }
  133.  
  134.  
  135.  
  136. /*************************************
  137.  *
  138.  *    Playfield RAM write handler
  139.  *
  140.  *************************************/
  141.  
  142. WRITE_HANDLER( rampart_playfieldram_w )
  143. {
  144.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  145.     int newword = COMBINE_WORD(oldword, data);
  146.     int x, y;
  147.  
  148.     if (oldword != newword)
  149.     {
  150.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  151.  
  152.         /* track color usage */
  153.         x = offset % 512;
  154.         y = offset / 512;
  155.         if (x < XDIM && y < YDIM)
  156.         {
  157.             color_usage[(oldword >> 8) & 0xff]--;
  158.             color_usage[oldword & 0xff]--;
  159.             color_usage[(newword >> 8) & 0xff]++;
  160.             color_usage[newword & 0xff]++;
  161.         }
  162.  
  163.         /* mark scanlines dirty */
  164.         atarigen_pf_dirty[y] = 1;
  165.     }
  166. }
  167.  
  168.  
  169.  
  170. /*************************************
  171.  *
  172.  *    Periodic scanline updater
  173.  *
  174.  *************************************/
  175.  
  176. void rampart_scanline_update(int scanline)
  177. {
  178.     /* update the MOs from the SLIP table */
  179.     atarigen_mo_update_slip_512(atarigen_spriteram, 0, scanline, &atarigen_spriteram[0x3f40]);
  180. }
  181.  
  182.  
  183.  
  184. /*************************************
  185.  *
  186.  *    Main refresh
  187.  *
  188.  *************************************/
  189.  
  190. void rampart_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  191. {
  192.     /* remap if necessary */
  193.     if (update_palette())
  194.         memset(atarigen_pf_dirty, 1, YDIM);
  195.  
  196.     /* update the cached bitmap */
  197.     {
  198.         int x, y;
  199.  
  200.         for (y = 0; y < YDIM; y++)
  201.             if (atarigen_pf_dirty[y])
  202.             {
  203.                 int xx = 0;
  204.                 const UINT8 *src = &atarigen_playfieldram[512 * y];
  205.  
  206.                 /* regenerate the line */
  207.                 for (x = 0; x < XDIM/2; x++)
  208.                 {
  209.                     int bits = READ_WORD(src);
  210.                     src += 2;
  211.                     plot_pixel(atarigen_pf_bitmap, xx++, y, Machine->pens[bits >> 8]);
  212.                     plot_pixel(atarigen_pf_bitmap, xx++, y, Machine->pens[bits & 0xff]);
  213.                 }
  214.                 atarigen_pf_dirty[y] = 0;
  215.             }
  216.     }
  217.  
  218.     /* copy the cached bitmap */
  219.     copybitmap(bitmap, atarigen_pf_bitmap, 0, 0, 0, 0, NULL, TRANSPARENCY_NONE, 0);
  220.  
  221.     /* render the motion objects */
  222.     atarigen_mo_process(mo_render_callback, bitmap);
  223.  
  224.     /* update onscreen messages */
  225.     atarigen_update_messages();
  226. }
  227.  
  228.  
  229.  
  230. /*************************************
  231.  *
  232.  *    Palette management
  233.  *
  234.  *************************************/
  235.  
  236. static const UINT8 *update_palette(void)
  237. {
  238.     UINT16 mo_map[16];
  239.     int i, j;
  240.  
  241.     /* reset color tracking */
  242.     memset(mo_map, 0, sizeof(mo_map));
  243.     palette_init_used_colors();
  244.  
  245.     /* update color usage for the mo's */
  246.     atarigen_mo_process(mo_color_callback, mo_map);
  247.  
  248.     /* rebuild the playfield palette */
  249.     for (i = 0; i < 256; i++)
  250.         if (color_usage[i])
  251.             palette_used_colors[0x000 + i] = PALETTE_COLOR_USED;
  252.  
  253.     /* rebuild the motion object palette */
  254.     for (i = 0; i < 16; i++)
  255.     {
  256.         UINT16 used = mo_map[i];
  257.         if (used)
  258.         {
  259.             palette_used_colors[0x100 + i * 16 + 0] = PALETTE_COLOR_TRANSPARENT;
  260.             for (j = 1; j < 16; j++)
  261.                 if (used & (1 << j))
  262.                     palette_used_colors[0x100 + i * 16 + j] = PALETTE_COLOR_USED;
  263.         }
  264.     }
  265.  
  266.     return palette_recalc();
  267. }
  268.  
  269.  
  270.  
  271. /*************************************
  272.  *
  273.  *    Motion object palette
  274.  *
  275.  *************************************/
  276.  
  277. static void mo_color_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  278. {
  279.     const unsigned int *usage = Machine->gfx[0]->pen_usage;
  280.     UINT16 *colormap = param;
  281.     int code = data[1] & 0x7fff;
  282.     int color = data[2] & 0x000f;
  283.     int hsize = ((data[3] >> 4) & 7) + 1;
  284.     int vsize = (data[3] & 7) + 1;
  285.     int tiles = hsize * vsize;
  286.     UINT16 temp = 0;
  287.     int i;
  288.  
  289.     for (i = 0; i < tiles; i++)
  290.         temp |= usage[code++];
  291.     colormap[color] |= temp;
  292. }
  293.  
  294.  
  295.  
  296. /*************************************
  297.  *
  298.  *    Motion object rendering
  299.  *
  300.  *************************************/
  301.  
  302. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  303. {
  304.     const struct GfxElement *gfx = Machine->gfx[0];
  305.     struct osd_bitmap *bitmap = param;
  306.     struct rectangle pf_clip;
  307.  
  308.     /* extract data from the various words */
  309.     int hflip = data[1] & 0x8000;
  310.     int code = data[1] & 0x7fff;
  311.     int xpos = (data[2] >> 7) + 4;
  312.     int color = data[2] & 0x000f;
  313.     int ypos = 512 - (data[3] >> 7);
  314.     int hsize = ((data[3] >> 4) & 7) + 1;
  315.     int vsize = (data[3] & 7) + 1;
  316.  
  317.     /* adjust for height */
  318.     ypos -= vsize * 8;
  319.  
  320.     /* adjust the final coordinates */
  321.     xpos &= 0x1ff;
  322.     ypos &= 0x1ff;
  323.     if (xpos >= XDIM) xpos -= 0x200;
  324.     if (ypos >= YDIM) ypos -= 0x200;
  325.  
  326.     /* determine the bounding box */
  327.     atarigen_mo_compute_clip_8x8(pf_clip, xpos, ypos, hsize, vsize, clip);
  328.  
  329.     /* draw the motion object */
  330.     atarigen_mo_draw_8x8(bitmap, gfx, code, color, hflip, 0, xpos, ypos, hsize, vsize, clip, TRANSPARENCY_PEN, 0);
  331. }
  332.